#include "stdafx.h"
#include "cmdlineoptions.h"
#include "getopt.h"

CCmdLineOptions::CCmdLineOptions()
	: maxMeanDifference(std::numeric_limits<double>::quiet_NaN()),
	maxMaxDifference(std::numeric_limits<double>::quiet_NaN())
{
}

bool CCmdLineOptions::Parse(int argc, wchar_t** argv)
{
	static const struct option long_options[] =
	{
		{ _T("verbose"),	 no_argument,		0, _T('v') },
		{ _T("brief"),		 no_argument,		0, _T('b') },
		{ _T("file1"),		 required_argument, 0, _T('1') },
		{ _T("file2"),		 required_argument, 0, _T('2') },
		{ _T("maxDiff"),	 required_argument, 0, _T('d') },
		{ _T("maxMeanDiff"), required_argument, 0, _T('m') },
		{ 0, 0, 0, 0}
	};

	for (;;)
	{
		int option_index;
		int c = getopt_long(argc, argv, L"vb1:2:md", long_options, &option_index);

		/* Detect the end of the options. */
		if (c == -1)
		{
			break;
		}

		switch (c)
		{
		case L'v':
			this->verbosityLevel = 99;
			break;
		case L'b':
			this->verbosityLevel = 1;
			break;
		case L'1':
			this->filenameA = optarg;
			break;
		case L'2':
			this->filenameB = optarg;
			break;
		case L'd':
			this->maxMaxDifference = parseDouble(optarg);
			break;
		case L'm':
			this->maxMeanDifference = parseDouble(optarg);
			break;
		}
	}

	return true;
}

const std::wstring& CCmdLineOptions::GetFilenameA() const
{
	return this->filenameA;
}

const std::wstring& CCmdLineOptions::GetFilenameB() const
{
	return this->filenameB;
}

int CCmdLineOptions::GetVerbosityLevel() const
{
	return verbosityLevel;
}

bool CCmdLineOptions::GetIsMaximumGiven() const
{
	if (isnan(this->maxMaxDifference) && isnan(this->maxMeanDifference))
	{
		return false;
	}

	return true;
}

double CCmdLineOptions::GetMaximumMaxDifference() const
{
	return this->maxMaxDifference;
}

double CCmdLineOptions::GetMaximumMeanDifference() const
{
	return this->maxMeanDifference;
}

double CCmdLineOptions::parseDouble(const wchar_t* sz)
{
	wchar_t* endptr;
	double value = wcstod(sz, &endptr);
	if (*endptr)
	{
		return 0;
	}

	return value;
}
